package com.jdbc.util;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;

import com.jdbc.util.JDBC_Util;
import com.mysql.jdbc.Connection;

public abstract class BaseDAO<T> {
	
	private Class<T> clazz = null;
	
	{
		//获取子类的父类的泛型
		Type genericSuperclass = this.getClass().getGenericSuperclass();
		ParameterizedType paramType = (ParameterizedType) genericSuperclass;
		Type[] typeArguments = paramType.getActualTypeArguments();//获取父类泛型参数
		clazz = (Class<T>) typeArguments[0];
	}

	//通用增删改(考虑事务)
	public int superUpdate(Connection conn,String sql,Object ... args) {
		PreparedStatement ps = null;
		try {
			//sql预编译
			ps = conn.prepareStatement(sql);
			for (int i = 0; i < args.length; i++) {
				ps.setObject(i+1, args[i]);
			}
			//执行
			//ps.execute();
			return ps.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		//资源关闭
		}finally {
			JDBC_Util.closeResource(null, ps);
		}
		return 0;
	}
	
	//通用查询(考虑事务)(返回列表)
	public List<T> superSelect(Connection conn,String sql,Object ... args) {
		PreparedStatement ps = null;
		ResultSet rs = null;
		ArrayList<T> list = new ArrayList<T>();
		try {
			conn = JDBC_Util.getConnection();
			ps = conn.prepareStatement(sql);
			if(args!=null) {
				for (int i = 0; i < args.length; i++) {
					ps.setObject(i+1, args[i]);
				}
			}
			//获取结果集
			rs = ps.executeQuery();
			//获取结果集元数据
			ResultSetMetaData rsmd = rs.getMetaData();
			//获取元数据列数
			int count = rsmd.getColumnCount();
			while(rs.next()) {
				T t = clazz.newInstance();
				//处理每行数据
				for (int i = 0; i < count; i++) {
					//获取属性值
					Object objValue = rs.getObject(i+1);
					//获取属性名
					String columnName = rsmd.getColumnLabel(i+1);
					
					//getColumnName() 获取列名(不推荐)
					//getColumnLabel() 获取别名 无别名默认列名
					//通过反射找到私有属性
					Field field = clazz.getDeclaredField(columnName);
					//设置访问私有属性
					field.setAccessible(true);
					//进行赋值
					field.set(t, objValue);
				}
				list.add(t);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JDBC_Util.closeResource(null, ps ,rs);
		}
		return list;
	}
	
	//用于查询特殊值
	public <T> T getValue(Connection conn,String sql,Object ... args) {
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			ps = conn.prepareStatement(sql);
			for (int i = 0; i < args.length; i++) {
				ps.setObject(i+1, args[i]);
			}
			
			rs = ps.executeQuery();
			if(rs.next()) {
				return (T)rs.getObject(1);
			}
			return null;
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JDBC_Util.closeResource(null, ps, rs);
		}
		return null;
	}

	
	
	
	
	
	
	
	
	
	
	
	
	
}
